home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / pcl4c341.zip / XYPACKET.C < prev   
Text File  |  1992-12-24  |  10KB  |  330 lines

  1. #include <stdio.h>
  2. #include <fcntl.h>
  3. #include <sys\types.h>
  4. #include <sys\stat.h>
  5.  
  6. #include "pcl4c.h"
  7. #include "term.h"
  8. #include "ascii.h"
  9.  
  10. #define DEBUG 0
  11. #define FALSE 0
  12. #define TRUE !FALSE
  13.  
  14. #define MAXTRY 5
  15. #define LIMIT 20
  16.  
  17. extern GetChar();
  18. extern PutChar();
  19. extern SayError();
  20. extern DisplayLine();
  21.  
  22. int TxPacket(Port,PacketNbr,PacketSize,Buffer,NCGchar)
  23. int Port;            /* COM port [0..3] */
  24. int PacketNbr;       /* Packet # to send */
  25. int PacketSize;      /* Packet size ( must be 128 or 1024 ) */
  26. char Buffer[];       /* Data buffer */
  27. char NCGchar;        /* NAK, 'C', or 'G' */
  28. {int  i;
  29.  int Code;
  30.  unsigned short CheckSum;
  31.  int Attempt;
  32.  int PacketType;
  33.  char temp[81];
  34.  /* begin */
  35. #if DEBUG
  36. printf("[TxP: COM%d PacketNbr=%d PacketSize=%d NCGchar=%c]",
  37.     1+Port,PacketNbr,PacketSize,NCGchar);
  38. #endif
  39.  /* better be 128 or 1024 packet length */
  40.  if(PacketSize==1024) PacketType = STX;
  41.  else PacketType = SOH;
  42.  PacketNbr &= 0x00ff;
  43.  /* make up to MAXTRY attempts to send this packet */
  44.  for(Attempt=1;Attempt<=MAXTRY;Attempt++)
  45.      {/* send SOH/STX  */
  46.       Code = PutChar(Port,PacketType);
  47.       /* send packet # */
  48.       Code = PutChar(Port,PacketNbr);
  49.       /* send 1's complement of packet */
  50.       Code = PutChar(Port,255-PacketNbr);
  51.       /* send data */
  52.       CheckSum = 0;
  53.       for(i=0;i<PacketSize;i++)
  54.           {Code = PutChar(Port,Buffer[i]);
  55.            if(NCGchar==NAK) CheckSum += Buffer[i];
  56.            else CheckSum = UpdateCRC(CheckSum, Buffer[i]);
  57.           }
  58.       /* send checksum */
  59.       if(NCGchar==NAK)
  60.           {Code = PutChar(Port,CheckSum & 0x00ff );
  61.           }
  62.       else
  63.           {Code = PutChar(Port, (CheckSum>>8) & 0x00ff );
  64.            Code = PutChar(Port, CheckSum & 0x00ff );
  65.           }
  66.       /* no ACK to wait for if 'G' */
  67.       if(NCGchar=='G')
  68.          {if(PacketNbr==0) SioDelay(SHORT_WAIT*ONE_SECOND/2);
  69.           return(TRUE);
  70.          }
  71.       /* wait for receivers ACK */
  72.       Code = GetChar(Port,LONG_WAIT*ONE_SECOND);
  73.       if((char)Code==CAN)
  74.           {DisplayLine("*** Canceled by REMOTE ***",NULL,0);
  75.            return(FALSE);
  76.           }
  77.       if((char)Code==ACK) return(TRUE);
  78.       if((char)Code!=NAK)
  79.           {PacketError(Port,PacketNbr,Attempt,"Out of sync");
  80.            return(FALSE);
  81.           }
  82.       /* Attempt again */
  83.      }/* end -- for(Attempt) */
  84.  /* can't send packet ! */
  85.  SayError(Port,"packet timeout (3 NAKs)");
  86.  return(FALSE);
  87. } /* end -- TxPacket */
  88.  
  89. int RxPacket(Port,PacketNbr,PacketSizePtr,Buffer,NCGchar,EOTptr)
  90. int Port;            /* COM port [0..3] */
  91. int PacketNbr;       /* Packet # expected */
  92. int *PacketSizePtr;  /* Pointer to PacketSize received ( 128 or 1024) */
  93. char Buffer[];       /* 1024 byte data buffer */
  94. char NCGchar;        /* NAK, C, or G */
  95. int *EOTptr;         /* Pointer to EOT flag */
  96. {int i;
  97.  int Code;
  98.  int Attempt;
  99.  int RxPacketNbr;
  100.  int RxPacketNbrComp;
  101.  unsigned short CheckSum;
  102.  unsigned short RxCheckSum;
  103.  unsigned short RxCheckSum1, RxCheckSum2;
  104.  /*char PacketType;*/
  105.  char temp[81];
  106.  /* begin */
  107. #if DEBUG
  108. printf("[RxP: COM%d PacketNbr=%d NCGchar=%c EOTflag=%d]",
  109.     1+Port,PacketNbr,NCGchar,*EOTptr);
  110. #endif
  111.  PacketNbr &= 0x00ff;
  112.  for(Attempt=1;Attempt<=MAXTRY;Attempt++)
  113.      {/* wait for SOH / STX */
  114.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  115.       if(Code==-1)
  116.           {PacketError(Port,PacketNbr,Attempt,"timed out waiting for SOH/STX");
  117.            return(FALSE);
  118.           }
  119.       switch((char)Code)
  120.           {
  121.            case SOH:
  122.                /* 128 byte buffer incoming */
  123.                /*PacketType = SOH;*/
  124.                *PacketSizePtr = 128;
  125.                break;
  126.            case STX:
  127.                /* 1024 byte buffer incoming */
  128.                /*PacketType = STX;*/
  129.                *PacketSizePtr = 1024;
  130.                break;
  131.            case CAN:
  132.                 /* sender has canceled ! */
  133.                 DisplayLine("*** Canceled by REMOTE ***",NULL,0);
  134.                 return(FALSE);
  135.            case EOT:
  136.                 /* all packets have been sent */
  137.                 Code = PutChar(Port,ACK);
  138.                 *EOTptr = TRUE;
  139.                 return(TRUE);
  140.            default:
  141.                 /* error ! */
  142.                 sprintf(temp,"Expecting SOH/STX/EOT/CAN not %xH",(char)Code);
  143.                 PacketError(Port,PacketNbr,Attempt,temp);
  144.                 return(FALSE);
  145.           }
  146.       /* receive packet # */
  147.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  148.       if(Code==-1)
  149.         {PacketError(Port,PacketNbr,Attempt,"timed out waiting for packet number");
  150.          return(FALSE);
  151.         }
  152.       RxPacketNbr = 0x00ff & Code;
  153.       /* receive 1's complement */
  154.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  155.       if(Code==-1)
  156.         {PacketError(Port,PacketNbr,Attempt,"timed out waiting for complement of packet #");
  157.          return(FALSE);
  158.         }
  159.       RxPacketNbrComp = 0x00ff & Code;
  160.       /* verify packet number */
  161.       if(RxPacketNbr+RxPacketNbrComp!=255)
  162.           {PacketError(Port,PacketNbr,Attempt,"Bad packet number");
  163.            return(FALSE);
  164.           }
  165.       /* receive data */
  166.       CheckSum = 0;
  167.       for(i=0;i<*PacketSizePtr;i++)
  168.           {Code = GetChar(Port,LONG_WAIT*ONE_SECOND);
  169.            if(Code==-1)
  170.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for data for packet #");
  171.                     return(FALSE);
  172.                    }
  173.            Buffer[i] = Code;
  174.            /* compute CRC or checksum */
  175.            if(NCGchar!=NAK) CheckSum = UpdateCRC(CheckSum,Code);
  176.            else CheckSum = (CheckSum + Code) & 0x00ff;
  177.           }
  178.       /* receive CRC/checksum */
  179.       if(NCGchar!=NAK)
  180.           {/* receive 2 byte CRC */
  181.            Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  182.            if(Code==-1)
  183.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 1st CRC byte");
  184.                     return(FALSE);
  185.                    }
  186.            RxCheckSum1 = Code & 0x00ff;
  187.            Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  188.            if(Code==-1)
  189.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for 2nd CRC byte");
  190.                     return(FALSE);
  191.                    }
  192.            RxCheckSum2 = Code & 0x00ff;
  193.            RxCheckSum = (RxCheckSum1<<8) | RxCheckSum2;
  194.           }
  195.       else
  196.           {/* receive one byte checksum */
  197.            Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  198.            if(Code==-1)
  199.                    {PacketError(Port,PacketNbr,Attempt,"timed out waiting for checksum");
  200.                     return(FALSE);
  201.                    }
  202.            RxCheckSum = Code & 0x00ff;
  203.           }
  204.       /* don't send ACK if 'G' */
  205.       if(NCGchar=='G') return(TRUE);
  206.       /* checksum OK ? */
  207.       if(RxCheckSum!=CheckSum)
  208.           {DisplayLine("Bad packet checksum",NULL,0);
  209.            Code = PutChar(Port,NAK);
  210.           }
  211.       /* packet number OK ? */
  212.       else if(RxPacketNbr!=PacketNbr)
  213.           {DisplayLine("Bad packet number",NULL,0);
  214.            Code = PutChar(Port,NAK);
  215.           }
  216.       else
  217.           {/* ACK the packet */
  218.            PutChar(Port,ACK);
  219.            return(TRUE);
  220.           } /* end if */
  221.      } /* end -- for(Attempt) */
  222.  /* can't receive packet */
  223.  SayError(Port,"RX packet timeout");
  224.  return(FALSE);
  225. } /* end -- RxPacket */
  226.  
  227. PacketError(Port,Packet,Attempt,MsgPtr)
  228. int Port;
  229. int Packet;
  230. int Attempt;
  231. char *MsgPtr;
  232. {char temp[81];
  233.  sprintf(temp,"Packet %d : Attempt %d : %s",Packet,Attempt,MsgPtr);
  234.  return( SayError(Port,temp) );
  235. }
  236.  
  237. int TxStartup(Port,NCGcharPtr)
  238. int Port;
  239. char *NCGcharPtr;
  240. {int i;
  241.  int Code;
  242. #if DEBUG
  243.  printf("### TxStartup");
  244. #endif
  245.  /* clear Rx buffer */
  246.  SioRxFlush(Port);
  247.  /* wait for receivers start up NAK, 'C', or 'G' */
  248.  for(i=1;i<LIMIT;i++)
  249.      {if(SioKeyPress())
  250.           {SayError(Port,"Aborted by user");
  251.            return(FALSE);
  252.           }
  253.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  254.       if(Code==-1) continue;
  255.       /* received a byte */
  256.       if((char)Code==NAK)
  257.           {*NCGcharPtr = NAK;
  258. #if DEBUG
  259.            printf("(CS) OK\n");
  260. #endif
  261.            return(TRUE);
  262.           }
  263.       if((char)Code=='C')
  264.           {*NCGcharPtr = 'C';
  265. #if DEBUG
  266.            printf("(CRC) OK\n");
  267. #endif
  268.            return(TRUE);
  269.           }
  270.       if((char)Code=='G')
  271.           {*NCGcharPtr = 'G';
  272. #if DEBUG
  273.            printf("(G) OK\n");
  274. #endif
  275.            return(TRUE);
  276.           }
  277.      } /* end -- for(i) */
  278.  /* no response */
  279.  SayError(Port,"No response from receiver");
  280.  return(FALSE);
  281. } /* end -- TxStartup */
  282.  
  283.  
  284. int RxStartup(Port,NCGcharPtr)
  285. int Port;
  286. char *NCGcharPtr;
  287. {int i;
  288.  int Code;
  289. #if DEBUG
  290.  printf("### RxStartup");
  291.  printf(" %c[%xH]",*NCGcharPtr,*NCGcharPtr);
  292. #endif
  293.  /* clear Rx buffer */
  294.  SioRxFlush(Port);
  295.  /* Send NAKs, 'C's, or 'G's */
  296.  for(i=1;i<LIMIT;i++)
  297.      {if(SioKeyPress())
  298.           {DisplayLine("*** Canceled by USER ***",NULL,0);
  299.            return(FALSE);
  300.           }
  301.       /* stop attempting CRC/'G' after 1st 4 tries */
  302.       if((*NCGcharPtr!=NAK)&&(i==5)) *NCGcharPtr = NAK;
  303.       /* tell sender that I am ready to receive */
  304.       Code = PutChar(Port,*NCGcharPtr);
  305.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  306.       if(Code==-1) continue;
  307.       /* no error -- must be incoming byte -- push byte back onto queue ! */
  308.       SioUnGetc(Port,(char)Code);
  309. #if DEBUG
  310.       printf("OK\n");
  311. #endif
  312.       return(TRUE);
  313.      } /* end -- for(i) */
  314.  /* no response */
  315.  SayError(Port,"No response from sender");
  316.  return(FALSE);
  317. } /* end -- RxStartup */
  318.  
  319. int TxEOT(Port)
  320. int Port;
  321. {int i;
  322.  int Code;
  323.  for(i=0;i<10;i++)
  324.      {Code = PutChar(Port,EOT);
  325.       /* await response */
  326.       Code = GetChar(Port,SHORT_WAIT*ONE_SECOND);
  327.       if((char)Code==ACK) return(TRUE);
  328.      } /* end -- for(i) */
  329.   return(FALSE);
  330.  } /* end -- TxEOT */